home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / SDKs / Now Utilities Plug Ins 6.0 / API Stuff / Now Tabs Plug Ins ƒ / Battery Plug In ƒ / Main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-07  |  6.7 KB  |  224 lines  |  [TEXT/KAHL]

  1. // Battery Plug In for Now Tabs
  2. // ©1996 Now Software, Inc, Now Utilities Division
  3. // 
  4. // written by: Henry Carstens, 3/2/96
  5. //
  6. // This plug in displays the current status of a powerbook or Duo's battery:
  7. // - whether or not it is charging
  8. // - the percentage of charge remaining
  9. // - the approximate time remaining on this battery
  10. //
  11.  
  12. #include "Main.h"
  13. #include "Power.h"
  14. #include "Gestalt.h"
  15.  
  16. #define canGetBatteryTimeMask      0x07
  17. #define chargerConnectedMask    0x05
  18. #define chargerChargingMask        0x06
  19. #define batteryInstalledMask    0x07
  20.  
  21. // This routine sets up the plug in definition version: kPlugInInformationVersionOne in this rev
  22. // and the plug in type:  kBatteryPlugInType.  Your own plug-ins will have their own types.
  23. // We'll want our plug in routines called when the Tabs menu is prepared
  24. // and when our plug in is selected if we are going to 'say' anything (speech mgr).
  25. pascal void main(PlugInInformation *plugInInformation)
  26. {
  27.     plugInInformation->version = kPlugInInformationVersionOne;
  28.     plugInInformation->plugInType = kBatteryPlugInType;
  29.     plugInInformation->PrepareMenu = &PrepareMenu;
  30.     plugInInformation->HandleMenuItemSelected = &HandleMenuItemSelected;
  31. }
  32.  
  33. // Use this routine to build your menu item
  34. // In our case we'll check to see if the PowerManager is available
  35. // and then determing the battery status.
  36. // We'll also use this routine to set up our globals.
  37. pascal void PrepareMenu(InstantAccessInformation *information, short asPreview)
  38. {
  39.     long                battery;
  40.     short                batteryCount;
  41.     BatteryInfo            batteryInfo;
  42.     BatteryTimeRec        batterySecs;
  43.     Str255                batteryString;
  44.     Boolean                hasBatteryTime;
  45.     OSErr                err;
  46.     long                features;
  47.     short                index;
  48.     MenuItemInformation    menuItem;
  49.     Byte                power;
  50.     double                realPower;
  51.     long                response;
  52.     Byte                status;
  53.     Str15                tempStr;
  54.     Str15                tempStr2;
  55.     unsigned long        timeRemaining;
  56.  
  57.     // Check to see if the Power Manager exists on this machine
  58.     err = Gestalt(gestaltPowerMgrAttr, &response);
  59.     if ( ( err != noErr) || (response == 0) ) {            // gestaltPwrMgrExists == 0
  60.         goto error;
  61.     }
  62.  
  63.     // Check to see if the charger is connected
  64.     err = BatteryStatus(&status,&power);
  65.     if (err != noErr) goto error;
  66.  
  67.     // Find out what features of the Power Manager we can use
  68.     features = PMFeatures();
  69.     
  70.     // see if we can get the time to charge or time remaining
  71.     hasBatteryTime = features && canGetBatteryTimeMask;
  72.  
  73.     // get number of batteries
  74.     batteryCount = BatteryCount();
  75.  
  76.     // Now, we'll build up a little battery database
  77.     // which we'll display in our menu
  78.     for (index = 1; index <= batteryCount; index++) {
  79.         
  80.         batteryString[0] = 0;
  81.  
  82.         // get the info for each battery
  83.         GetScaledBatteryInfo(index, &batteryInfo);
  84.         
  85.         // is there a battery installed?
  86.         if (!(batteryInfo.flags && batteryInstalledMask)) {
  87.             continue;
  88.         }
  89.  
  90.         if (hasBatteryTime) {
  91.             GetBatteryTimes(index, &batterySecs);
  92.             
  93.             if  ( (status && chargerConnMask) && (batteryInfo.flags && chargerConnectedMask) && (batteryInfo.flags && chargerChargingMask) ) {
  94.                 timeRemaining = batterySecs.timeUntilCharged;
  95.             } else {
  96.                 timeRemaining = batterySecs.expectedBatteryTime;
  97.             }
  98.             
  99.             // set sign bit to 0
  100.             BitClr(&timeRemaining, 0);
  101.             
  102.             timeRemaining = timeRemaining / 60;
  103.  
  104.             NumToString(timeRemaining, tempStr);
  105.  
  106.         } else {
  107.             tempStr[0] = 0;
  108.         }
  109.  
  110.         // start w/ the battery status message
  111.         BlockMove("Battery ", &batteryString[1], 8);
  112.         batteryString[0] = 8;
  113.  
  114.         // add the battery number
  115.         if (batteryCount > 1) {
  116.             NumToString(index,tempStr2);
  117.             BlockMove(&tempStr2[1], &batteryString[batteryString[0] + 1], tempStr2[0]);
  118.             batteryString[0] += tempStr2[0];
  119.         }
  120.  
  121.         // check for unknown time remaining - over 10 hours
  122.         if (timeRemaining > 600) {
  123.             tempStr[0] = 0;
  124.         }
  125.  
  126.         // finish the string
  127.         BlockMove("Status: ", &batteryString[batteryString[0] + 1], 8);
  128.         batteryString[0] += 8;
  129.         
  130.         if ( (status && chargerConnMask) && (batteryInfo.flags && chargerConnectedMask) && (batteryInfo.flags && chargerChargingMask) )  {
  131.             
  132.             // battery is charged if overflow is true
  133.             if (status && chargeOverFlowMask) {
  134.                 BlockMove("Charged ", &batteryString[batteryString[0] + 1], 7);
  135.                 batteryString[0] += 7;
  136.             } else {
  137.                 BlockMove("Charging ", &batteryString[batteryString[0] + 1], 9);
  138.                 batteryString[0] += 9;
  139.             }
  140.  
  141.         } else {
  142.             // we know the time remaining
  143.             if (tempStr[0] != 0) {
  144.                 BlockMove("Remaining ", &batteryString[batteryString[0] + 1], 10);
  145.                 batteryString[0] += 10;
  146.  
  147.             // we don't know the time remaining
  148.             } else {
  149.                 BlockMove("Discharging", &batteryString[batteryString[0] + 1], 11);
  150.                 batteryString[0] += 11; 
  151.             }
  152.         }
  153.  
  154.         // time remaining - check for no time value
  155.         if (tempStr[0] != 0) {
  156.             BlockMove(&tempStr[1], &batteryString[batteryString[0] + 1], tempStr[0]);
  157.             batteryString[0] += tempStr[0];
  158.  
  159.             BlockMove(" minutes", &batteryString[batteryString[0] + 1], 8);
  160.             batteryString[0] += 8;
  161.         }
  162.  
  163.         // Move our constructed menu string into the menuItem.text variable
  164.         // Always use kMenuItemTextSize in this routine
  165.         BlockMove(batteryString, menuItem.text, kMenuItemTextSize);
  166.         
  167.         // First, let's add a divider to seperate us from the rest of the world
  168.         if (index == 1) {
  169.             menuItem.version = kMenuItemInformationVersionOne;
  170.             menuItem.classification = kMiscellaneousClassification;
  171.             menuItem.type = kDividerMenuItemType;
  172.             menuItem.id = 1;
  173.             menuItem.enabled = false;
  174.             menuItem.style = 0;
  175.             menuItem.mark = 0;
  176.             menuItem.hasSubMenu = FALSE;
  177.             menuItem.subMenu = nil;
  178.             menuItem.refCon = 0;
  179.             menuItem.owningPlugInType = kBatteryPlugInType;
  180.  
  181.             // This call adds the menuItem to the Now Tabs menu
  182.             (*information->AddMenuItem)(&menuItem);
  183.         }
  184.     
  185.         // Here we fill out the rest of the menuItem information
  186.         // You'll need to insert your plug in type in the owningPlugInType field        
  187.         menuItem.type = kTextMenuItemType;
  188.         menuItem.id = index + 1;
  189.         menuItem.enabled = true;
  190.         
  191.         // This call adds the menuItem to the Now Tabs menu
  192.         (*information->AddMenuItem)(&menuItem);
  193.  
  194.         if (index == batteryCount) {
  195.  
  196.             // Add a divider below        
  197.             menuItem.type = kDividerMenuItemType;
  198.             menuItem.id = index + 2;
  199.             menuItem.enabled = false;
  200.             
  201.             // This call adds the menuItem to the Now Tabs menu
  202.             (*information->AddMenuItem)(&menuItem);
  203.         }
  204.     }
  205.  
  206. error:;
  207.  
  208. }
  209.  
  210. // If we had allocated any memory during the call to menu select that we
  211. // still needed to clean up, we would do the clean up here
  212. pascal void CleanUpAfterMenuSelect(InstantAccessInformation *information, short asPreview)
  213. {
  214.     
  215. }
  216.  
  217. // This routine is called when your menu item is selected by the user so add your
  218. // selection routines here...
  219. pascal void HandleMenuItemSelected(InstantAccessInformation *information, MenuItemInformation *menuItem)
  220. {
  221.     // If speech manager is present, say "You have x minutes of power remaining."
  222.     // If speech manager is present, say "Dammit Jim, I'm a doctor, not a battery specialist"
  223. }
  224.